package cn.darkhorse.ticket.store.service.impl;

import cn.darkhorse.exception.ServiceException;
import cn.darkhorse.ticket.basis.dao.TicketProductDao;
import cn.darkhorse.ticket.store.dao.TicketInventoryDao;
import cn.darkhorse.ticket.store.dto.TicketProductDetailsDTO;
import cn.darkhorse.ticket.store.mapper.TicketInventoryMapper;
import cn.darkhorse.ticket.store.pojo.TicketInventory;
import cn.darkhorse.ticket.store.service.TicketInventoryService;
import cn.darkhorse.ticket.store.vo.TicketInventoryVO;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.stereotype.Service;
import sun.awt.geom.AreaOp;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 库存信息 服务实现类
 * </p>
 *
 * @author wangxinghui
 * @since 2024-01-16
 */
@Service
public class TicketInventoryServiceImpl extends ServiceImpl<TicketInventoryMapper, TicketInventory> implements TicketInventoryService {
	
	
	
	public ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
	
	@Resource
	TicketInventoryDao ticketInventoryDao;
	@Resource
	TicketProductDao productDao;
	
	/**
	 * 列表
	 * @param productCode
	 * @param productName
	 * @param productTypeId
	 * @return
	 */
	@Override
	public List<TicketInventory> list(String productCode, String productName, Long productTypeId) {
		Map<String,Object> params = new HashMap<>();
		if(StringUtils.isNotBlank(productCode)){
			params.put("productCode",productCode);
		}
		if(StringUtils.isNotBlank(productName)){
			params.put("productName",productName);
		}
		if(null != productTypeId){
			params.put("productTypeId",productTypeId);
		}
		List<TicketInventory> inventoryList = ticketInventoryDao.list(params);
		return inventoryList;
	}
	
	@Override
	public void add(List<TicketProductDetailsDTO> warehousingSubs) {
	    if(null == warehousingSubs ||warehousingSubs.isEmpty()){
	    	return;
		}
		List<TicketInventory> inventories = new ArrayList<>();
		List<TicketInventory> inventoryList = list();
		Map<String, TicketInventory> inventoryMap = inventoryList.stream().collect(Collectors.toMap(k -> k.getProductId() + "-" + k.getWarehouseInfoId(), Function.identity()));
		rwl.writeLock().lock();
		try {
			warehousingSubs.forEach(item->{
				TicketInventory inventory = new TicketInventory();
				String key = item.getProductId()+"-"+item.getWarehouseInfoId();
				TicketInventory ti = inventoryMap.get(key);
				if(!Objects.isNull(ti)){
					inventory = ti;
					inventory.setQuantity(ti.getQuantity().add(item.getQuantity()));
				}else {
					BeanUtil.copyProperties(item,inventory,new String[]{"id","gmt_create","gmt_modified"});
				}
				inventories.add(inventory);
			});
			saveOrUpdateBatch(inventories);
		} catch (Exception e) {
			e.printStackTrace();
			throw new ServiceException(e.getMessage());
		}finally {
			rwl.writeLock().unlock();
		}
	}
	
	@Override
	public TicketInventoryVO view(Long productId) {
		TicketInventoryVO vo = new TicketInventoryVO();
		List<TicketInventoryVO.Details> detailsList = new ArrayList<>();
		LambdaQueryWrapper<TicketInventory> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(TicketInventory::getProductId,productId);
		List<TicketInventory> inventoryList = list(queryWrapper);
		if(inventoryList.isEmpty()){
			return vo;
		}
		TicketInventory inventory = inventoryList.get(0);
		BeanUtil.copyProperties(inventory,vo);
		//获取产品单位
		String productUnityName = productDao.getProductUnityName(productId);
		BigDecimal total = BigDecimal.ZERO;
		for(TicketInventory item:inventoryList){
			total = total.add(item.getQuantity());
			TicketInventoryVO.Details details = new TicketInventoryVO.Details();
			details.setQuantity(item.getQuantity());
			details.setWarehouseInfoName(item.getWarehouseInfoName());
			details.setUnityName(productUnityName);
			detailsList.add(details);
		}
		vo.setTotal(total);
		vo.setDetails(detailsList);
		return vo;
	}
	
	
}
